export const guid = () => {
  function S4() {
    return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1)
  }

  return (S4() + S4() + '-' + S4() + '-' + S4() + '-' + S4() + '-' + S4() + S4() + S4())
}

/**
 * Promise.all并发限制
 * @param {Number} poolLimit 并发数，
 * @param {Array} array 数组里的参数，
 * @param {function} iteratorFn Promise方法
 */
export const asyncPool = (poolLimit, array, iteratorFn) => {
  let i = 0
  const ret = []
  const executing = []
  const enqueue = function() {
    // 边界处理，array为空数组
    if (i === array.length) {
      return Promise.resolve()
    }
    // 每调一次enqueue，初始化一个promise
    const item = array[i]
    const index = i
    const p = Promise.resolve().then(() => iteratorFn(item, array, index))
    i++
    // 放入promises数组
    ret.push(p)
    // promise执行完毕，从executing数组中删除
    const e = p.then(() => executing.splice(executing.indexOf(e), 1))
    // 插入executing数字，表示正在执行的promise
    executing.push(e)
    // 使用Promise.race，每当executing数组中promise数量低于poolLimit，就实例化新的promise并执行
    let r = Promise.resolve()
    if (executing.length >= poolLimit) {
      r = Promise.race(executing)
    }
    // 递归，直到遍历完array
    return r.then(() => enqueue())
  }
  return enqueue().then(() => Promise.all(ret))
}
/**
 * Returns a random number between min (inclusive) and max (exclusive)
 */
export function getRandomArbitrary(min, max) {
  return Math.random() * (max - min) + min;
}

/**
 * Returns a random integer between min (inclusive) and max (inclusive).
 * The value is no lower than min (or the next integer greater than min
 * if min isn't an integer) and no greater than max (or the next integer
 * lower than max if max isn't an integer).
 * Using Math.round() will give you a non-uniform distribution!
 */
export function getRandomInt(min, max) {
  min = Math.ceil(min);
  max = Math.floor(max);
  return Math.floor(Math.random() * (max - min + 1)) + min;
}
